#include "libutil.h"

/*  safe_malloc ()
 *  
 *  Call calloc () and abort if the specified amount of
 *  memory cannot be allocated.
 */
void *
safe_malloc (size_t size)
{
  void *mem_block = NULL;

  if ((mem_block = calloc (1, size)) == NULL) {
    fprintf (stderr, "ERROR: safe_malloc(%zu) cannot allocate memory.",
             size);
    exit (EXIT_FAILURE);
  }
  return (mem_block);
}

/*  safe_realloc ()
 *  
 *  Call realloc () and abort if the specified amount of
 *  memory cannot be allocated.
 */
void *
safe_realloc (void *old_mem, size_t new_size)
{
  if ((old_mem = realloc (old_mem, new_size)) == NULL) {
    fprintf (stderr, "ERROR: safe_realloc() cannot allocate" 
             "%u blocks of memory.\n", (unsigned int) new_size);
    exit (EXIT_FAILURE);
  }
  return (old_mem);
}

/*
 * safe_strdup ()
 *
 * Safe version of strdup avoid buffer overflow, etc.
 *
 */
char *
safe_strdup (const char *str)
{
  char *copy = NULL;

  if (str == NULL) {
    fprintf (stderr, "ERROR safe_strdup(): str == NULL");
    exit (EXIT_FAILURE);
  }

  copy = safe_malloc ((strlen (str) + 1) * sizeof (char));

  (void) strcpy (copy, str);

  return (copy);
}

/* currw = 0 means word, nonword otherwise */
char * 
parse_file_char (FILE *data_file, int *currw)
{
  char *text;
  size_t size;
  int c = 0, buf_len = 0;

  size = MAX_WORD_LEN * (sizeof (char))+1;
  text = safe_malloc (size);

  memset (text, 0, size);

  while ((c = getc (data_file)) != EOF) {
    if (buf_len == MAX_WORD_LEN) {
      ungetc (c, data_file);
      text[buf_len] = '\0';
      return (text);
    }
    if (c == 0) {
      text[buf_len] = '\0';
      return (text);
    }
    if (isalnum (c)) {
      if (buf_len == 0) {
        *currw = 0;
      }
      if (*currw == 1) {
        ungetc (c, data_file);
        text[buf_len] = '\0';
        return (text);
      } else {
        text[buf_len++] = c;
      }
      *currw = 0;
    } else {
      if (buf_len == 0) {
        *currw = 1;
      }
      if (*currw == 0) {
        ungetc (c, data_file);
        text[buf_len] = '\0';
        return (text);
      } else {
        text[buf_len++] = c;
      }
      *currw = 1;
    }
  }
  if (buf_len > 0) {
    text[buf_len] = '\0';
    return (text);
  }
  return (NULL);
}
    
